home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / hips / sources / 3d-tools / 3drotate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-06  |  7.8 KB  |  285 lines

  1. /*
  2. % 3DROTATE - rotate 3D image into another 3D image for displaying and looking
  3. %    the different surface of the image.
  4. %
  5. %    Copyright (c)    1990    Jin, Guojun
  6. */
  7. char    usage[]="options\n\
  8. -l (look left side) slice vertically (y-z plane, parallel to Y axle).\n\
  9.     If continuously doing, it goes to left->bottom->front. It is exactly\n\
  10.     same as 3drotate90.\n\
  11. -t specify slicing horizontally (x-z surface, parallel to X axle),\n\
  12.     top goes to front. It is default. If continuously rotating,\n\
  13.     then -> back -> bottom, and finally back to front again.\n\
  14.     this option is similar to in 3drotate90, but it put upper left corner\n\
  15.     to lower left corner. So rotation goes to top, rear(back),\n\
  16.     bottom and back to front again. It can continiously work for\n\
  17.     all surface and a faster than 3drotate90.\n\
  18. -p @ doing slicing diagnally and @ gives choice for parallel to\n\
  19.     which axle, and -a # gives angle which range is -90 -- +90 degree.\n\
  20.     But you can specify any angle, the program can convert it into this\n\
  21.     range.\n\
  22. % Note:    \n\
  23. %    If upper left corner keeping required, use 3drotate90 and 3drotate180\n\
  24. %    to get every certain rotations.\n";
  25.  
  26. /*
  27. # Very Improtant Note:
  28. @
  29. @    MUST include <math.h> in this file
  30. @
  31. @ AUTHOR:    Guojun Jin - LBL    11/15/90
  32. */
  33.  
  34. #include "header.def"
  35. #include "imagedef.h"
  36. #include <math.h>
  37.  
  38. int    one_more;
  39. U_IMAGE    uimg;
  40.  
  41. #define    inbuf    uimg.src
  42. #define    obuf    uimg.dest
  43. #define    rows    uimg.height
  44. #define    cols    uimg.width
  45.  
  46. #define    GValue()    arget(argc, argv, &i, &c)
  47.  
  48.  
  49. main(argc, argv)
  50. int    argc;
  51. char**    argv;
  52. {
  53. int    slice_dir, xyz;
  54. /* !!!    input number is start from 1 and convert to from 0. See line 110 */
  55. int    bgn_cln=1, bgn_row=1, frmsNew=0;
  56. MType    i, f, r, c,
  57.     rowsNew, clnsNew, fsizeNew, fsize, width;
  58. float    angle=45, riF, cjF,
  59.     interpolation();
  60. double    sinl, cosl;
  61.  
  62. format_init(&uimg, IMAGE_INIT_TYPE, HIPS, -1, *argv, "S20-1");
  63.  
  64. for (i=1; i<argc; i++)
  65.     if (*argv[i] == '-' || *argv[i] == '+') {
  66.     c=1;
  67.     switch (argv[i][c++]) {
  68.     case 'a':
  69.         angle = GValue();    break;
  70.     case 'c':
  71.         bgn_cln = GValue();    break;
  72.     case 'r':
  73.         bgn_row = GValue();    break;
  74.     case 'l':
  75.     case 't':
  76.         slice_dir = argv[i][1];    break;
  77.     case 'p':
  78.         slice_dir = xyz = argv[i][c];    break;
  79.     case 'n':
  80.         frmsNew = GValue();    break;
  81.     case 'o':
  82.         if (avset(argc, argv, &i, &c, 1) &&
  83.             (out_fp=freopen(argv[i]+c, "wb", stdout)))    break;
  84.     default:
  85. errout:        usage_n_options(usage, i, argv[i]);
  86.     }
  87.     }
  88.     else if ((in_fp=freopen(argv[i], "rb", stdin)) == NULL)
  89.         syserr("input file %s not found", argv[i]);
  90.  
  91. io_test(fileno(in_fp), goto    errout);
  92.  
  93. angle -= (int)(angle/180) * 180;
  94. if (fabs(angle) > 90)
  95.     angle -= 180;
  96. if (slice_dir < 'x' && !angle && fabs(angle) == 90)
  97.     syserr("use %s -l or -t options", *argv);
  98.  
  99. (*uimg.header_handle)(HEADER_READ, &uimg, 0, 0);
  100. uimg.pxl_out = uimg.pxl_in;
  101. uimg.o_form = uimg.in_form;
  102. fsize = cols * rows;
  103.  
  104. if (bgn_row > rows)    bgn_row = rows;
  105. if (bgn_cln > cols)    bgn_cln = cols;
  106. if (bgn_cln)    bgn_cln--;
  107. if (bgn_row)    bgn_row--;
  108.  
  109. inbuf = nzalloc(uimg.pxl_in, fsize*uimg.frames, "inbuf");
  110.  
  111. uimg.load_all = uimg.frames;
  112. (*uimg.std_swif)(FI_LOAD_FILE, &uimg, 0, No);
  113.  
  114. switch(slice_dir)
  115. {
  116. case 't':    /*    Z-X => xyz = 'x'    look from top    */
  117. default:
  118.     if (!frmsNew || frmsNew > rows-bgn_row)
  119.         frmsNew = rows - bgn_row;
  120.     i = rows;    rows = uimg.frames;
  121.     uimg.frames = frmsNew;    frmsNew += bgn_row;
  122.     fsizeNew = cols * rows;
  123.     obuf = nzalloc(uimg.pxl_in, fsizeNew, "hbuf");
  124.  
  125.     {
  126.     char    mesgbuf[1024];
  127.     sprintf(mesgbuf,
  128.     "horizontal slicing at row%d (%d frames). Rotate top to front\n",
  129.         bgn_row+1, uimg.frames);
  130.     msg("%s", mesgbuf);
  131.     (*uimg.header_handle)(ADD_DESC, &uimg, mesgbuf);
  132.     }
  133.     (*uimg.header_handle)(HEADER_WRITE, &uimg, argc, argv, True);
  134.  
  135.     switch (uimg.pxl_in){
  136.     case 1:    {
  137.     register byte    *inbp, *obp, *tmpp;
  138.         for (r=bgn_row; r<frmsNew; r++){
  139.         inbp = tmpp = (byte*)inbuf + r*cols;
  140.         obp = (byte*)obuf + (rows-1)*cols;
  141.         for (f=rows; f--; inbp=tmpp+=fsize, obp-=cols<<1)
  142.             for (c=cols; c--;)
  143.             *obp++ = *inbp++;
  144.         if (fwrite(obuf, uimg.pxl_in, fsizeNew, stdout) != fsizeNew)
  145.             syserr("error during h write.");
  146.         }
  147.     }break;
  148.     case 2:    {
  149.     register short    *inbp, *obp, *tmpp;
  150.         for (r=bgn_row; r<frmsNew; r++){
  151.         inbp = tmpp = (short*)inbuf + r*cols;
  152.         obp = (short*)obuf + (rows-1)*cols;
  153.         for (f=rows; f--; inbp=tmpp+=fsize, obp-=cols<<1)
  154.             for (c=cols; c--;)
  155.             *obp++ = *inbp++;
  156.         if (fwrite(obuf, uimg.pxl_in, fsizeNew, stdout) != fsizeNew)
  157.             syserr("error during h write.");
  158.         }
  159.     }break;
  160.     case 4:    {
  161.     register int    *inbp, *obp, *tmpp;
  162.         for (r=bgn_row; r<frmsNew; r++){
  163.         inbp = tmpp = (int*)inbuf + r*cols;
  164.         obp = (int*)obuf + (rows-1)*cols;
  165.         for (f=rows; f--; inbp=tmpp+=fsize, obp-=cols<<1)
  166.             for (c=cols; c--;)
  167.             *obp++ = *inbp++;
  168.         if (fwrite(obuf, uimg.pxl_in, fsizeNew, stdout) != fsizeNew)
  169.             syserr("error during h write.");
  170.         }
  171.     }
  172.     }    /* end of switch(uimg.pxl_in)    */
  173.     break;
  174. case 'l':    /*    look from left side.    Y-Z => xyz = 'z'    */
  175.     if (!frmsNew || frmsNew > cols-bgn_cln)
  176.         frmsNew = cols - bgn_cln;
  177.     i = cols;    cols = rows;
  178.     rows = uimg.frames;    uimg.frames = frmsNew;
  179.     fsizeNew = cols * rows;
  180.     obuf = zalloc(uimg.pxl_in, fsizeNew, "vbuf");
  181.  
  182.     {
  183.     char    mesgbuf[1024];
  184.     sprintf(mesgbuf,
  185.     "vertical slicing at column%d (%d frames). Rotate to left & turn left\n",
  186.         bgn_cln+1, frmsNew);
  187.     msg("%s", mesgbuf);
  188.     (*uimg.header_handle)(ADD_DESC, &uimg, mesgbuf);
  189.     }
  190.     (*uimg.header_handle)(HEADER_WRITE, &uimg, argc, argv, True);
  191.  
  192.     for (c=bgn_cln; c<frmsNew; c++){
  193.         switch(uimg.pxl_in){
  194.         case 1:    {
  195.         register byte    *inbp, *tmpp, *obp;
  196.         tmpp = (byte*)inbuf;
  197.         obp = (byte*)obuf;
  198.         for (f=0, tmpp+=c; f < rows; f++, tmpp+=fsize)
  199.             for (r=0, inbp=tmpp; r<cols; r++, inbp+=i)/* old_cln */
  200.             *obp++ = *inbp;
  201.         }break;
  202.         case 2:    {
  203.         register short    *inbp, *tmpp, *obp;
  204.         tmpp = (short*)inbuf;
  205.         obp = (short*)obuf;
  206.         for (f=0, tmpp+=c; f < rows; f++, tmpp+=fsize)
  207.             for (r=0, inbp=tmpp; r<cols; r++, inbp+=i)
  208.             *obp++ = *inbp;
  209.         }break;
  210.         case 4:    {
  211.         register int    *inbp, *tmpp, *obp;
  212.         tmpp = (int*)inbuf;
  213.         obp = (int*)obuf;
  214.         for (f=0, tmpp+=c; f < rows; f++, tmpp+=fsize)
  215.             for (r=0, inbp=tmpp; r<cols; r++, inbp+=i)/* old_cln */
  216.             *obp++ = *inbp;
  217.         }
  218.         }    /* end of switch (uimg.pxl_in)    */
  219.         if (fwrite(obuf, uimg.pxl_in, fsizeNew, stdout) != fsizeNew)
  220.         syserr("error during v write.");
  221.     }
  222.     break;
  223. case 'x':
  224. case 'y':
  225. case 'z':{
  226. register char    *inbp, *obp;
  227. int    *bp, *buf = (int*)zalloc(uimg.pxl_in, fsize, "buf");
  228.     message("diagnal slicing\n");
  229.     angle *= M_PI / 180.0;
  230.     cosl = cos(angle);
  231.     sinl = sin(angle);
  232.     rowsNew = rows / cosl;
  233.     clnsNew = cols / sinl;
  234.     fsizeNew= rowsNew * clnsNew;
  235.     if (angle > 0 && rowsNew * sinl > cols - bgn_cln)
  236.         rowsNew = (cols - bgn_cln) / sinl;
  237.     else if (angle < 0 && rowsNew * sinl < -bgn_cln)
  238.         rowsNew = -bgn_cln / sinl;
  239.  
  240.     width = (xyz == 'x') ? cols : (xyz == 'y') ?
  241.         (uimg.frames-1) * rows * cols :
  242.         (angle < 0)? fsize - 1 : fsize + 1;
  243.  
  244.     bp = buf;    inbp = inbuf;    /* convert to integer    */
  245.     for(i = 0; i < fsize; i++)
  246.         *bp++ = (int)(*inbp++ & 0xFF);
  247.     obp = obuf = zalloc(uimg.pxl_in, fsizeNew, "dbuf");
  248.     for(r = bgn_row; r < rowsNew; r++)    /* rowsNew = rows/cosl    */
  249.         for(c = 0; c < clnsNew; c++){    /* colsNew = frames    */
  250.         riF = cosl * r + bgn_row;
  251.         cjF = sinl * r + bgn_cln;
  252.         if (r && c)
  253.         *obp++ = (char)interpolation(bp + (int)floor(c * cosl), width, riF, cjF);
  254.         else    *obp++ = bp[r * cols + c];
  255.         }
  256.     cols = clnsNew;    rows = rowsNew;
  257.     if (fwrite(obuf, uimg.pxl_in, fsizeNew, stdout) != fsizeNew)
  258.         syserr("error during write d.");
  259. }
  260. }    /* end of switch(dir)    */
  261. return(0);
  262. }
  263.  
  264.  
  265. float   interpolation(cur_pos, width, riF, cjF)
  266. register int    *cur_pos, width;
  267. float        riF, cjF;
  268. {
  269. float    lamio, lami1, lamjo, lamj1;
  270. float    p00, p01, p10, p11;
  271. register int    ri, cj;
  272.  
  273. ri = riF;    cj = cjF;
  274. lami1 = riF - ri;    /* the % of fraction position    */
  275. lamio = 1.0 - lami1;    /* the % of regular position    */
  276. lamj1 = cjF - cj;
  277. lamjo = 1.0 - lamj1;
  278.  
  279. p00 = *(cur_pos - width - one_more) * lamio;
  280. p01 = *(cur_pos - width) * lamio;
  281. p10 = *(cur_pos + width - one_more) * lami1;
  282. p11 = *cur_pos * lami1;
  283. return    (lamjo*(p00 + p10) + lamj1*(p01 + p11));
  284. }
  285.